package solution155;

import java.util.Stack;

public class MinStack {
    private long min;
    private Stack<Long> stack;

    public MinStack(){
        stack=new Stack<>();
    }

    // 将x-min入栈，这样当栈顶元素小于0,时，说明，实际入栈的值为最小值
    public void push(int x) {
        if (stack.isEmpty()){
            stack.push(0L);
            min=x;
        }else{
            stack.push(x-min);//Could be negative if min value needs to change
            if (x<min) min=x;
        }
    }
    // 将x-min入栈，这样当新加入的值x更小时，x-min<0，更新min=x，
    // 若stack.pop()<0，说明x<min,跟新过min(min=x),所以删除后要重新计算min,
    // 由于stack.pop()=x-min(删除栈顶元素后对应的min),所以，min=x-stack.pop(),而这里x就是stack.pop()元素对应的最小值min
    // 即，min(删除栈顶元素后对应的min)=min(stack.pop()元素对应的最小值min)-stack.pop();
    public void pop() {
        if (stack.isEmpty()) return;

        long pop=stack.pop();

        if (pop<0)  min=min-pop;//If negative, increase the min value

    }
    // 将x-min入栈，这样当新加入的值x更小时，x-min<0，更新min=x，也就是若入栈的值小于0，说明此时top()对应的x就是min,
    // 也就是，在top()时，若内部堆stack的peek()返回的是小于0的数,那么top()返回的就是min。
    // 或者说，stack.peek()<0,说明x<min, 更新过min为x,那么x=top()=min,及top()返回min;
    // 而如果stack.peek()>0，说明x>min，没有更新过min，而stack.peek()=x-min,那么top()返回的值x=stack.peek()+min,
    public int top() {
        long top=stack.peek();
        if (top>0){
            return (int)(top+min);
        }else{
            return (int)(min);
        }
    }

    public int getMin() {
        return (int)min;
    }
}
